-
Notifications
You must be signed in to change notification settings - Fork 625
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support UDP multicast. #618
Conversation
8639b33
to
d5f9e78
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks really good, didn't manage to go through everything but need to head to a meeting now
Sources/NIO/Channel.swift
Outdated
@@ -337,6 +337,23 @@ public enum ChannelLifecycleError: Error { | |||
case inappropriateOperationForState | |||
} | |||
|
|||
/// This should be inside of `ChannelError` but we keep it separate to not break API. | |||
// TODO: For 2.0: bring this inside of `ChannelError`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mind filing an issue for that with the 2.0 milestone? Just so we won't forget and then we get nice github support of how many outstanding things
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, see #620.
Sources/NIO/Channel.swift
Outdated
|
||
/// An attempt was made to join a multicast group that does not correspond to a multicast | ||
/// address. | ||
case notAMulticastAddress(SocketAddress) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe illegalMulticastAddress
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
or invalidMulticastAddress
Sources/NIO/MulticastChannel.swift
Outdated
/// - parameters: | ||
/// - group: The IP address corresponding to the relevant multicast group. | ||
/// - returns: An `EventLoopFuture` that will be notified once the operation is complete. | ||
func joinGroup(_ group: SocketAddress) -> EventLoopFuture<Void> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shouldn't this be only in the proto extension? There's only one good implementation for that
Sources/NIO/MulticastChannel.swift
Outdated
/// - group: The IP address corresponding to the relevant multicast group. | ||
/// - interface: The interface on which to join the given group, or `nil` to allow the kernel to choose. | ||
/// - returns: An `EventLoopFuture` that will be notified once the operation is complete. | ||
func joinGroup(_ group: SocketAddress, interface: NIONetworkInterface?) -> EventLoopFuture<Void> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shouldn't this be only in the proto extension? There's only one good implementation for that
Sources/NIO/MulticastChannel.swift
Outdated
/// - parameters: | ||
/// - group: The IP address corresponding to the relevant multicast group. | ||
/// - returns: An `EventLoopFuture` that will be notified once the operation is complete. | ||
func leaveGroup(_ group: SocketAddress) -> EventLoopFuture<Void> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shouldn't this be only in the proto extension? There's only one good implementation for that
Sources/NIO/SocketChannel.swift
Outdated
if eventLoop.inEventLoop { | ||
self.performGroupOperation0(group, interface: interface, promise: promise, operation: .join) | ||
} else { | ||
eventLoop.execute { self.performGroupOperation0(group, interface: interface, promise: promise, operation: .join) } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
newlines?
Sources/NIO/SocketChannel.swift
Outdated
if eventLoop.inEventLoop { | ||
self.performGroupOperation0(group, interface: interface, promise: promise, operation: .leave) | ||
} else { | ||
eventLoop.execute { self.performGroupOperation0(group, interface: interface, promise: promise, operation: .leave) } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
newlines?
Sources/NIO/SocketChannel.swift
Outdated
// IPv6 binding with no specific interface requested. | ||
let multicastRequest = ipv6_mreq(ipv6mr_multiaddr: groupAddress.address.sin6_addr, ipv6mr_interface: 0) | ||
try self.socket.setOption(level: CInt(IPPROTO_IPV6), name: operation.optionName(level: IPPROTO_IPV6), value: multicastRequest) | ||
case (.v4, .some(.v6)), (.v6, .some(.v4)), (.v4, .some(.unixDomainSocket)), (.v6, .some(.unixDomainSocket)): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what's the odds that the 4.0 or 4.1 compiler can't see this is exhaustive ;)
//===----------------------------------------------------------------------===// | ||
|
||
import NIO | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: extra newline
Sources/NIOMulticastChat/main.swift
Outdated
// guard case .v4(let targetAddress) = targetInterface.address else { | ||
// fatalError("Parsed target address as non-IPv4: \(targetInterface.address)") | ||
// } | ||
// datagramBootstrap = datagramBootstrap.channelOption(ChannelOptions.socket(SocketOptionLevel(IPPROTO_IP), IP_MULTICAST_IF), value: targetAddress.address.sin_addr) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we want this commented out code?
e56afef
to
57e1a67
Compare
Ok, ready for re-review. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
almost there, just one minor naming thing
/// | ||
/// - returns: An `EventLoopFuture` containing the value of the socket option, or | ||
/// any error that occurred while retrieving the socket option. | ||
public func getIpMulticastIf() -> EventLoopFuture<in_addr> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Swift naming conventions say getIPMulticastIF
as abbreviations are all caps.
/// | ||
/// - returns: An `EventLoopFuture` containing the value of the socket option, or | ||
/// any error that occurred while retrieving the socket option. | ||
public func getIpv6MulticastLoop() -> EventLoopFuture<CUnsignedInt> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
here IPV6
case unknownLocalAddress | ||
|
||
/// The address family of the multicast group was not valid for this `Channel`. | ||
case badMulticastGroupAddressFamily |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should this also take the family as parameter (just like we did for notAMulticastAddress
) ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It could, but it would really need both the channel address family and the provided address family to make much sense. Should we do that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nah... I think that would be too much :) Ship it !
case badMulticastGroupAddressFamily | ||
|
||
/// The address family of the provided multicast group join is not valid for this `Channel`. | ||
case badInterfaceAddressFamily |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same question as above
Sources/NIO/Channel.swift
Outdated
|
||
/// An attempt was made to join a multicast group that does not correspond to a multicast | ||
/// address. | ||
case notAMulticastAddress(SocketAddress) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
or invalidMulticastAddress
Motivation: A large number of very useful protocols are implemented using multicast with UDP. As a result, it would be helpful to add support for joining and leaving IP multicast groups using SwiftNIO. Modifications: - Defines a MulticastChannel protocol for channels that support joining and leaving multicast groups. - Adds an implementation of MulticastChannel to DatagramChannel. - Adds a interfaceIndex property to NIONetworkInterface. - Adds if_nametoindex to the Posix enum. - Adds a isMulticast computed property to SocketAddress - Adds a demo multicast chat application. - Add a number of multicast-related socket options to SocketOptionProvider. Result: NIO users will be able to write channels that handle multicast UDP.
57e1a67
to
b9ece72
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks very much, I'm happy this!
Motivation:
A large number of very useful protocols are implemented using multicast
with UDP. As a result, it would be helpful to add support for joining and
leaving IP multicast groups using SwiftNIO.
Modifications:
leaving multicast groups.
Result:
NIO users will be able to write channels that handle multicast UDP.